use crate::globals::constants::*;
use crate::globals::variables;
use crate::internal::logger;
use crate::tasks::{
    AsyncTask, file_task::FileTimeTask, http_task::HttpServerTask, udp_task::UdpTimeTask,
};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use tokio::runtime::Runtime;
use windows_service::{
    Result,
    service::{
        ServiceControl, ServiceControlAccept, ServiceExitCode, ServiceState, ServiceStatus,
        ServiceType,
    },
    service_control_handler::{self, ServiceControlHandlerResult},
};

// 服务类型 - 对于svchost DLL服务，使用SHARE_PROCESS
const SERVICE_TYPE: ServiceType = ServiceType::SHARE_PROCESS;

// 通道用于接收停止信号
lazy_static::lazy_static! {
    static ref SHUTDOWN_CHANNEL: Arc<Mutex<Option<std::sync::mpsc::Sender<()>>>> =
        Arc::new(Mutex::new(None));
}

// 服务控制处理函数
fn service_control_handler(control_event: ServiceControl) -> ServiceControlHandlerResult {
    match control_event {
        ServiceControl::Stop => {
            // 发送停止信号
            if let Some(tx) = SHUTDOWN_CHANNEL.lock().unwrap().as_ref() {
                let _ = tx.send(());
            }
            ServiceControlHandlerResult::NoError
        }
        ServiceControl::Interrogate => ServiceControlHandlerResult::NoError,
        _ => ServiceControlHandlerResult::NotImplemented,
    }
}

// 服务主函数
fn run_service() -> Result<()> {
    // 注册事件处理程序
    let status_handle = service_control_handler::register(SERVICE_NAME, service_control_handler)?;

    // 获取DLL路径并初始化全局变量
    let dll_path = match crate::internal::utils::get_current_dll_path() {
        Some(path) => path,
        None => {
            // 获取DLL路径失败，向服务管理控制器报告错误
            status_handle.set_service_status(ServiceStatus {
                service_type: SERVICE_TYPE,
                current_state: ServiceState::Stopped,
                controls_accepted: ServiceControlAccept::empty(),
                exit_code: ServiceExitCode::ServiceSpecific(1), // 使用自定义错误码1表示获取DLL路径失败
                checkpoint: 0,
                wait_hint: Duration::default(),
                process_id: None,
            })?;
            return Err(windows_service::Error::Winapi(std::io::Error::new(
                std::io::ErrorKind::NotFound,
                "无法获取DLL路径",
            )));
        }
    };

    // 转换路径字符串
    let path_str = match String::from_utf16(&dll_path) {
        Ok(path) => path,
        Err(_) => {
            // 路径字符串转换失败，向服务管理控制器报告错误
            status_handle.set_service_status(ServiceStatus {
                service_type: SERVICE_TYPE,
                current_state: ServiceState::Stopped,
                controls_accepted: ServiceControlAccept::empty(),
                exit_code: ServiceExitCode::ServiceSpecific(2), // 使用自定义错误码2表示路径字符串转换失败
                checkpoint: 0,
                wait_hint: Duration::default(),
                process_id: None,
            })?;
            return Err(windows_service::Error::Winapi(std::io::Error::new(
                std::io::ErrorKind::InvalidData,
                "DLL路径包含无效字符",
            )));
        }
    };

    // 初始化全局变量
    variables::init_dll_path(&path_str);

    // 创建一个通道用于接收停止信号
    let (shutdown_tx, shutdown_rx) = std::sync::mpsc::channel();

    // 存储发送端以便在控制处理程序中使用
    *SHUTDOWN_CHANNEL.lock().unwrap() = Some(shutdown_tx);

    // 告诉系统服务已启动
    status_handle.set_service_status(ServiceStatus {
        service_type: SERVICE_TYPE,
        current_state: ServiceState::Running,
        controls_accepted: ServiceControlAccept::STOP,
        exit_code: ServiceExitCode::Win32(0),
        checkpoint: 0,
        wait_hint: Duration::default(),
        process_id: None,
    })?;

    // #####################################
    // 您的服务代码在这里
    // #####################################

    // 创建tokio运行时
    let runtime = Runtime::new().unwrap();

    // 在tokio运行时中执行异步任务
    runtime.block_on(async {
        // 获取日志目录 - 使用全局变量（前面已经验证过DLL路径，这里可以直接使用）
        let log_dir = {
            let dir = variables::get_dll_directory().unwrap();
            let mut log_path = dir.clone();
            log_path.push("logs"); // 添加logs子目录
            log_path.to_string_lossy().to_string()
        };

        // 初始化日志系统 - 使用绝对路径
        if let Err(e) = logger::init_logger(&log_dir) {
            eprintln!("无法初始化日志记录器 {}: {:?}", log_dir, e);
            return;
        }
        logger::log_info(format!("日志路径: {}", log_dir));
        logger::log_info("服务启动中...");

        logger::log_info("创建停止标志...");
        // 创建一个可以被多个任务共享的停止标志
        let (stop_tx, stop_rx) = tokio::sync::watch::channel(false);

        logger::log_info("创建任务实例...");
        // 创建任务实例
        logger::log_info("创建UDP任务...");
        let udp_task = UdpTimeTask::new("127.0.0.1:11000", 1); // UDP服务器地址和间隔（秒）

        // 修改文件任务路径，使用DLL目录下的service_time.log文件
        logger::log_info("创建文件任务...");
        let file_path = {
            let mut path = variables::get_dll_directory().unwrap().clone();
            path.push("service_time.log");
            path.to_string_lossy().to_string()
        };
        let file_task = FileTimeTask::new(&file_path, 1); // 使用DLL目录下的日志文件和间隔（秒）

        logger::log_info("创建HTTP任务...");
        let http_task = HttpServerTask::new(28080); // 端口号

        // 启动任务
        logger::log_info("启动UDP任务...");
        let udp_handle = udp_task.start(stop_rx.clone());
        logger::log_info("启动文件任务...");
        let file_handle = file_task.start(stop_rx.clone());
        logger::log_info("启动HTTP任务...");
        let http_handle = http_task.start(stop_rx.clone());

        logger::log_info("收集任务句柄...");
        // 收集所有任务句柄
        let handles = vec![udp_handle, file_handle, http_handle];

        logger::log_info("服务启动成功...");
        // 等待停止信号
        loop {
            match shutdown_rx.recv_timeout(Duration::from_secs(1)) {
                Ok(_) | Err(std::sync::mpsc::RecvTimeoutError::Disconnected) => {
                    // 收到停止信号，通知所有异步任务停止
                    let _ = stop_tx.send(true);
                    break;
                }
                Err(std::sync::mpsc::RecvTimeoutError::Timeout) => (),
            }
        }

        logger::log_info("服务正在停止...");

        // 等待所有任务完成
        for handle in handles {
            let _ = handle.await;
        }
    });

    // #####################################

    // // 服务主循环（这里是同步代码）
    // loop {
    //     // 检查是否收到停止信号
    //     match shutdown_rx.recv_timeout(Duration::from_secs(1)) {
    //         Ok(_) | Err(std::sync::mpsc::RecvTimeoutError::Disconnected) => break,
    //         Err(std::sync::mpsc::RecvTimeoutError::Timeout) => (),
    //     }
    // }

    logger::log_info("服务停止完成");

    // 告诉系统服务已停止
    status_handle.set_service_status(ServiceStatus {
        service_type: SERVICE_TYPE,
        current_state: ServiceState::Stopped,
        controls_accepted: ServiceControlAccept::empty(),
        exit_code: ServiceExitCode::Win32(0),
        checkpoint: 0,
        wait_hint: Duration::default(),
        process_id: None,
    })?;

    Ok(())
}

// DLL服务入口点 - 这是svchost调用的函数
#[unsafe(no_mangle)]
#[allow(non_snake_case)]
pub extern "system" fn ServiceMain(_arg_c: u32, _arg_v: *mut *mut u16) {
    if let Err(e) = run_service() {
        // 由于日志系统未初始化，使用标准错误输出
        eprintln!("Service error: {:?}", e);
    }
}
